package com.midrange.rse_enhancements.chgmsg;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.rse.core.RSECorePlugin;
import org.eclipse.rse.core.events.ISystemRemoteChangeEvents;
import org.eclipse.rse.core.model.ISystemRegistry;
import org.eclipse.rse.core.model.SystemMessageObject;
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
import org.eclipse.rse.ui.SystemBasePlugin;
import org.eclipse.rse.ui.messages.SystemMessageDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;

import com.ibm.etools.iseries.services.qsys.api.IQSYSMessageDescription;
import com.ibm.etools.iseries.subsystems.qsys.commands.QSYSCommandSubSystem;
import com.ibm.etools.iseries.subsystems.qsys.objects.IRemoteObjectContext;
import com.ibm.etools.iseries.subsystems.qsys.objects.QSYSObjectSubSystem;
import com.ibm.etools.iseries.subsystems.qsys.objects.QSYSRemoteMessageDescription;
import com.ibm.etools.iseries.subsystems.qsys.objects.QSYSRemoteMessageFile;
import com.midrange.rse_enhancements.Activator;
import com.midrange.rse_enhancements.preferences.PreferenceConstants;

/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * Change message text action, invoked from popup menu on AS400 Message
 * 
 * @author David Gibbs
 *
 */

public class ChangeMessageTextAction implements IObjectActionDelegate {

	private ISystemRegistry registry = RSECorePlugin.getDefault().getSystemRegistry();

	private List<IQSYSMessageDescription> selectedMessages;

	private IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore();

	public ChangeMessageTextAction() {
		selectedMessages = new ArrayList<IQSYSMessageDescription>();
	}

	@Override
	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
		// nothing

	}

	protected Shell getShell() {
		return SystemBasePlugin.getActiveWorkbenchShell();
	}

	protected IQSYSMessageDescription getFirstSelectedRemoteFile() {
		IQSYSMessageDescription selected = null;
		
		if (selectedMessages.size() > 0) {
			selected = selectedMessages.get(0);
		} 
		
		return selected;
	}

	protected QSYSObjectSubSystem getSubSystem() {
		QSYSRemoteMessageDescription msg = (QSYSRemoteMessageDescription) getFirstSelectedRemoteFile();
		IRemoteObjectContext context = msg.getRemoteObjectContext();
		QSYSObjectSubSystem subsystem = context.getObjectSubsystem();

		return subsystem;
	}


	public QSYSCommandSubSystem getRemoteCmdSubSystem() {
		//get the Command subsystem associated with the current host
		QSYSObjectSubSystem subsystem = getSubSystem();
		QSYSCommandSubSystem cmdSubsystem = (QSYSCommandSubSystem) subsystem.getCmdSubSystem();

		return cmdSubsystem;
	}

	private static final String CHGMSGD_CMD = "QSYS/CHGMSGD MSGID({0}) MSGF({1}/{2}) SECLVL(''{3}'')";

	@Override
	public void run(IAction action) {

		Shell shell = getShell();

		IQSYSMessageDescription message = getFirstSelectedRemoteFile();

		String id = message.getID();

		QSYSRemoteMessageFile file = (QSYSRemoteMessageFile) message.getFile();

		try {
			message = file.getMessageDescription(id, new NullProgressMonitor());

			String library = file.getLibrary();
			String name = file.getName();

			EditMessageTextDialog dialog = new EditMessageTextDialog(shell, 
					message);
			
//			dialog.setMessageText(message.getHelp()); 

			if (dialog.open() == Window.OK) {

				String updatedText = dialog.getMessageText();

				String cmd = MessageFormat.format(CHGMSGD_CMD, message.getID(), 
						library, name, fixQuotes(updatedText));

				String humanCommand = MessageFormatter.formatForHumans(cmd);
				
				boolean confirmCommand = preferenceStore.getBoolean(
						PreferenceConstants.P_CONFIRM_UPDATE_MESSAGE);
				
				if (!confirmCommand || MessageDialog.openConfirm(shell, 
						"OK to run command", humanCommand)) {
					runCommand(cmd);

					registry.fireRemoteResourceChangeEvent(
							ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_CREATED, 
							message, file, getSubSystem(), null, null);

				}
			}
		} catch (SystemMessageException e) {
			SystemMessageDialog.displayMessage(e);
		} catch (Exception e) {
			SystemMessageDialog.displayExceptionMessage(shell, e);
		}
	}

	private static final char QUOTE = '\'';

	private final String fixQuotes(String input) {
		StringBuffer sb = new StringBuffer(input);

		for (int i=0;i<sb.length();i++) {
			if (sb.charAt(i) == QUOTE) {
				sb.insert(i++, QUOTE);
			}
		}

		return sb.toString();
	}



	public void runCommand(String command) throws Exception {
		QSYSCommandSubSystem cmdss = getRemoteCmdSubSystem();

		if (cmdss != null) {
			// Run the command in a visible shell
			Object[] errors = cmdss.runCommand(command);

			if (errors.length > 0) {
				StringBuffer sb = new StringBuffer();
				boolean errorOccurred = false;

				for (Object _smo : errors) {
					SystemMessageObject smo = (SystemMessageObject)_smo;
					if (smo.getType() != SystemMessageObject.MSGTYPE_INFO) {
						sb.append(smo.getMessage() + "\n");
						errorOccurred = true;
					}
				}

				if (errorOccurred) {
					MessageDialog.openError(getShell(), "Errors on command", 
							sb.toString());
				}
			}
		} else {
			MessageDialog.openError(getShell(), "No command subsystem", "Found no command subsystem");
		}

	}

	@Override
	public void selectionChanged(IAction action, ISelection selection) {
		selectedMessages = new ArrayList<IQSYSMessageDescription>();

		Iterator<?> theSet = ((IStructuredSelection) selection).iterator();
		while (theSet.hasNext()) {
			Object obj = theSet.next();
			if (obj instanceof IQSYSMessageDescription) {
				selectedMessages.add((IQSYSMessageDescription)obj);
			}
		}
	}

}
